// 引入SDK核心类，js文件根据自己业务，位置可自行放置
import QQMapWX from '../../../libs/qqmap-wx-jssdk.min.js'
import Schema from 'async-validator'
import { reqAddAddress, reqAddressInfo, reqUpdateAddress } from '../../../api/address'


Page({
    // 页面的初始数据
    data: {
        name: "", // 收货人
        phone: "",    // 手机号码
        provinceName: "", // 省
        provinceCode: "", // 省编码
        cityName: "", // 市
        cityCode: "", // 市编码
        districtName: "", // 区
        districtCode: "", // 市编码
        address: "",  // 详细地址
        fullAddress: "",  // 完整地址
        isDefault: false  // 是否设置为默认地址，0：不设置为默认地址，1：设置为默认地址
    },

    onLoad(options) {
        // 对核心类 QQMapWX 进行实例化，
        this.qqmapwx = new QQMapWX({
            // 使用自己申请的 key
            key: 'L4RBZ-PMUCQ-GVA5X-2W3DP-EOEEQ-WXBYR'
        })
        // 调用方法，实现更新的业务逻辑
        this.showAddressInfo(options.id)
    },
    // 用来处理更新相关的逻辑
    async showAddressInfo(id) {
        if (!id) return 

        // 将 id 挂载到当前页面的实例（this）上，方便在多个方法中使用 id
        this.addressId = id

        // 动态设置当前页面的标题
        wx.setNavigationBarTitle({
          title: '更新收货地址',
        })
        const { data } = await reqAddressInfo(id)
        // 将详情数据进行赋值，赋值医护，页面上就会回显要更新的地址信息
        this.setData(data)
    },
    // 获取用户地理位置信息
    async onLocation() {
        // 调用 wx.getSetting 获取用户所有授权的信息，查询到用户是否授权了位置信息
        // authSetting 只包含了小程序向用户请求的所有权限，同时包含了授权的结果【true, false】
        const { authSetting } = await wx.getSetting()
        // console.log(authSetting)

        // scope.userLocation 用户是否授权获取了地理位置信息
        // 如果小程序没有向用户发起过授权请求，authSetting 中就没有 scope.userLocation 属性
        // 如果用户点击了允许授权，返回值就是 true
        // 如果用户点击了拒绝授权，返回值就是 false
        // console.log(authSetting['scope.userLocation'])

        if (authSetting['scope.userLocation'] === false) {
            // 用户之前拒绝授权获取位置信息，用户再次发起了授权
            // 这时候需要使用一个弹窗询问用户是否进行授权
            const modalRes = await wx.modal({
                title: '授权提示',
                content: '需要获取地理位置信息，清确认授权'
            })

            // 如果用户点击了取消，说明用户拒绝了授权，需要给用户进行提示
            if (!modalRes) return wx.toast({title: '您拒绝了授权'})

            // 如果用户点击了确定，说明用户同意授权，需要打开微信客户端小程序授权页面
            const { authSetting } = await wx.openSetting()

            // 如果用户没有更新授权信息，需要给用户提示授权失败
            if (!authSetting['scope.userLocation']) 
                return wx.toast({title: '授权失败'})

            try {
                const res = await wx.getLocation()
                console.log("getLocation", res)
            } catch(error) {
                wx.toast({title: "您拒绝授权获取地理位置"})
            }
        } else {
            // 获取当前地理位置（精度、维度、高度等），如果用户拒绝授权以后，如果再次调用，不会弹出授权窗
            try {
                const res = await wx.getLocation()
                console.log("getLocation", res)
            } catch(error) {
                wx.toast({title: "您拒绝授权获取地理位置"})
            }
        }

        // 打开地图，让用户选择地理位置
        // latitude 维度, longitude 经度, name 搜索的地点
        const { latitude, longitude, name } = await wx.chooseLocation()
        // console.log(latitude, longitude, name)
        // 使用 reverseGeocoder 实例化方法进行逆地址解析
        this.qqmapwx.reverseGeocoder({
            location: {
                latitude, 
                longitude
            },
            success: (res) => {
                // console.log("reverseGeocoder", res)
                // 获取省市区，省市区编码
                const { adcode, province, city, district } = res.result.ad_info

                // 获取街道、门牌（街道、门牌 可能为空）
                const { street, street_number } = res.result.address_component

                // 获取标准地址
                const { standard_address } = res.result.formatted_addresses

                // 对获取的数据进行格式化、组织、然后赋值给 data 中的字段
                this.setData({
                    // 省
                    provinceName: province,
                    // 如果是省，前两位有值，后面 4 位是 0 (500112)
                    provinceCode: adcode.replace(adcode.substring(2, 6), '0000'),

                    // 市
                    cityName: city,
                    // 如果是市，前 4 位有值，后面 2 位是 0 (500112)
                    cityCode: adcode.replace(adcode.substring(4, 6), '00'),

                    // 区
                    districtName: district,
                    districtCode: district && adcode,

                    // 组织详细地址
                    address: street + street_number + name,
                    // 组织完整地址
                    fullAddress: standard_address + name
                })
            }
        })
    },

    // 对新增收货地址请求参数进行验证
    validatorAddress(params) {
        // 验证收货人，是否只包含大小写字母、数字和中文字符
        const nameRegExp = '^[a-zA-Z\\d\\u4e00-\\u9fa5]+$'
        // 验证手机号，是否符合中国大陆手机号码的格式
        const phoneReg = '^1(?:3\\d|4[4-9]|5[0-35-9]|6[67]|7[0-8]|8\\d|9\\d)\\d{8}$'

        // 定义验证规则
        const rules = {
            // key 验证规则的名字，名字需要和验证的数据保持一致
            name: [
                // required 是否必填项， message 如果验证失败，提示错误内容
                { required: true, message: '请输入收货人姓名' },
                // type 验证数据的类型
                // { type: 'string', message: 'name 不是字符串' },
                // min 最少位数，max 最大位数
                // { min: 2, max: 3, message: '名字最少2个字，最多3个字' },
                // pattern 使用正则对数据进行验证
                { pattern: nameRegExp, message: '收货人姓名不合法' },
                // validator 自定义验证规则
                // { validator: () => {} }
            ],
            phone: [
                { required: true, message: '清输入收货人手机号' },
                { pattern: phoneReg, message: '收货人手机号不合法' }
            ],
            provinceName: { required: true, message: '清选择收货人所在地区' },
            address: { required: true, message: '清输入详细地址' },
        }

        // 需要对构造函数进行实例化，同时传入验证规则
        const validator = new Schema(rules)

        return new Promise((resolve) => {
            // 需要调用 validate 方法，对数据进行验证
            // 第一个参数：需要验证的数据，要求数据是一个对象
            //  validate 方法只会验证和验证规则同名的字段
            // 第二个参数：是一个回调函数
            validator.validate(params, (errors, fields) => {
                // 如果验证成功，errors 是一个 null
                // 如果验证失败，errors 是一个数组，数组每一项是错误信息
                // fields 是需要验证的属性，属性值是一个数组，数组中也包含着错误信息
                if (errors) {
                    // console.log("验证失败")
                    // console.log(errors)
                    // console.log(fields)
                    // 如果验证失败，需要给用户进行提示
                    wx.toast({ title: errors[0].message })
                    // 如果属性值是 false，说明验证失败
                    resolve({ valid: false })
                } else {
                    // console.log("验证成功")
                    // 如果属性值是 true，说明验证成功
                    resolve({ valid: true })
                }
            })
        })
    },

    // 保存收货地址
    async saveAddrssForm(event) {
        // 组织参数
        const { provinceName, cityName, districtName, address, isDefault } = this.data

        // 需要发送的请求参数
        const params = {
            ...this.data,
            fullAddress: provinceName + cityName + districtName + address,
            isDefault: isDefault ? 1 : 0
        }

        // 对组织以后的参数进行验证，验证通过以后，需要调用新增的接口实现新增收货地址功能
        const { valid } = await this.validatorAddress(params)
        // 如果valid等于false，说明验证失败，就不执行后续的逻辑
        if (!valid) return

        // 如果 valid 等于 true，说明验证成功调用新增的接口实现新增收货地址功能
        const res = this.addressId ? await reqUpdateAddress(params) : await reqAddAddress(params)
        if (res.code === 200) {
            // 返回收货地址列表页面
            wx.navigateBack({
                success: () => {
                    // 需要给用户进行提示
                    wx.toast({ title: this.addressId ? '更新收货地址成功' : '新增收货地址成功' })
                }
            })
            
        }
    },

    // 省市区选择
    onAddressChange(event) {
        // console.log(event)

        const [provinceName, cityName, districtName] = event.detail.value
        const [provinceCode, cityCode, districtCode] = event.detail.code
        this.setData({
            provinceName, cityName, districtName,
            provinceCode, cityCode, districtCode
        })
    }
})